<?php

namespace App\Models\Setting;

use Eloquent;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;

/**
 * App\Models\Setting\Setting
 *
 * @property int         $id
 * @property string      $setting_key   键名
 * @property string      $setting_value 键值
 * @property string      $setting_name  名称
 * @property string      $setting_desc  描述
 * @property Carbon|null $created_at
 * @property Carbon|null $updated_at
 * @method static Builder|Setting newModelQuery()
 * @method static Builder|Setting newQuery()
 * @method static Builder|Setting query()
 * @method static Builder|Setting whereCreatedAt($value)
 * @method static Builder|Setting whereId($value)
 * @method static Builder|Setting whereSettingDesc($value)
 * @method static Builder|Setting whereSettingKey($value)
 * @method static Builder|Setting whereSettingName($value)
 * @method static Builder|Setting whereSettingValue($value)
 * @method static Builder|Setting whereUpdatedAt($value)
 * @mixin Eloquent
 */
class Setting extends Model
{
    use HasFactory;

    protected $table = 'setting';

    protected $fillable
        = [
            "setting_key",
            "setting_value",
            "setting_name",
            "setting_desc",
        ];

    public function getSettingName(): string
    {
        return $this->getAttribute('setting_name') ?: '';
    }

    /**
     * 火车票订票最大时间
     *
     * @return int
     */
    public function getTrainBookDay(): int
    {
        $key = 'train_book_day';
        return $this->getSettingValue($key);
    }

    private function getSettingValue(string $setting_key)
    {
        $setting = $this->getSetting($setting_key);
        return $setting?->getValue();
    }

    public function getSetting(string $setting_key): ?self
    {
        if ($setting = $this->getCache($setting_key)) {

        } else {
            $setting = $this->where('setting_key', $setting_key)->first();
            if ($setting) {
                $this->cached($setting_key, $setting);
            }
        }
        return $setting;
    }

    private function getCache(string $key): ?Setting
    {
        return Cache::has($this->cacheKey($key)) ? Cache::get($this->cacheKey($key)) : null;
    }

    private function cacheKey(string $key): string
    {
        return "Setting:{$key}";
    }

    private function cached(string $key, Setting $setting, $ttl = 24 * 3600)
    {
        Cache::put($this->cacheKey($key), $setting, $ttl);
    }

    public function getValue()
    {
        return $this->getAttribute('setting_value');
    }

    public function updateAndCache(Setting $setting, $setting_value)
    {
        if (!$setting_value) {
            return false;
        }

        if ($setting->getValue() == $setting_value) {
            return false;
        }

        $res = $setting->update([
            'setting_value' => $setting_value,
        ]);

        $this->cached($setting->getSettingKey(), $setting);
        return $res;
    }

    public function getSettingKey()
    {
        return $this->getAttribute('setting_key');
    }

    /**
     * 火车票订票显示月份
     *
     * @return int
     */
    public function TrainMonth(): int
    {
        $key = 'train_month';
        return $this->getSettingValue($key);
    }

    /**
     * 火车票线下订单-购票服务费
     *
     * @return float
     */
    public function TrainOfflineBookServiceFee(): float
    {
        $key = 'train_book_service_fee';
        return $this->getSettingValue($key);
    }

    /**
     * 火车票线下订单-改签服务费
     *
     * @return float
     */
    public function TrainOfflineChangeServiceFee(): float
    {
        $key = 'train_change_service_fee';
        return $this->getSettingValue($key);
    }

    /**
     * 火车票抢票高速服务费
     *
     * @return float
     */
    public function TrainSnapHighSpeedServiceFee(): float
    {
        $key = 'train_snap_high_speed_service_fee';
        return $this->getSettingValue($key);
    }

    /**
     * 火车票线下订单-退款服务费
     *
     * @return float
     */
    public function TrainOfflineRefundServiceFee(): float
    {
        $key = 'train_refund_service_fee';
        return $this->getSettingValue($key);
    }

}
